Completed
Push — master ( bdd11a...04b37b )
by
unknown
10s
created

EAN13.js ➔ ???   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22

Duplication

Lines 22
Ratio 100 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 4
c 4
b 0
f 0
nc 4
nop 2
dl 22
loc 22
rs 8.9197
1
// Encoding documentation:
2
// https://en.wikipedia.org/wiki/International_Article_Number_(EAN)#Binary_encoding_of_data_digits_into_EAN-13_barcode
3
4
import { SIDE_BIN, MIDDLE_BIN, EAN13_STRUCTURE } from './constants';
5
import encode from './encoder';
6
import Barcode from '../Barcode';
7
8
// Calculate the checksum digit
9
// https://en.wikipedia.org/wiki/International_Article_Number_(EAN)#Calculation_of_checksum_digit
10
const checksum = (number) => {
11
	const res = number
12
		.substr(0, 12)
13
		.split('')
14
		.map((n) => +n)
15
		.reduce((sum, a, idx) => (
16
			idx % 2 ? sum + a * 3 : sum + a
17
		), 0);
18
19
	return (10 - (res % 10)) % 10;
20
};
21
22
class EAN13 extends Barcode {
23
24
	constructor(data, options) {
25
		// Add checksum if it does not exist
26
		if (data.search(/^[0-9]{12}$/) !== -1) {
27
			data += checksum(data);
28
		}
29
30
		super(data, options);
31
32
		// Make sure the font is not bigger than the space between the guard bars
33
		this.fontSize = !options.flat && options.fontSize > options.width * 10
34
			? options.width * 10
35
			: options.fontSize;
36
37
		// Make the guard bars go down half the way of the text
38
		this.guardHeight = options.height + this.fontSize / 2 + options.textMargin;
39
40
		// Adds a last character to the end of the barcode
41
		this.lastChar = options.lastChar;
42
	}
43
44
	valid() {
45
		return (
46
			this.data.search(/^[0-9]{13}$/) !== -1 &&
47
			+this.data[12] === checksum(this.data)
48
		);
49
	}
50
51
	encode() {
52
		return this.options.flat
53
			? this.encodeFlat()
54
			: this.encodeGuarded();
55
	}
56
57
	get leftData() {
58
		return this.data.substr(1, 6);
59
	}
60
61
	get rightData() {
62
		return this.data.substr(7, 6);
63
	}
64
65
	// The "standard" way of printing EAN13 barcodes with guard bars
66
	encodeGuarded() {
67
		const textOptions = { fontSize: this.fontSize };
68
		const guardOptions = { height: this.guardHeight };
69
70
		const data = [
71
			{
72
				data: SIDE_BIN,
73
				options: guardOptions
74
			},
75
			{
76
				data: encode(this.leftData, EAN13_STRUCTURE[this.data[0]]),
77
				text: this.text.substr(1, 6),
78
				options: textOptions
79
			},
80
			{
81
				data: MIDDLE_BIN,
82
				options: guardOptions
83
			},
84
			{
85
				data: encode(this.rightData, 'RRRRRR'),
86
				text: this.text.substr(7, 6),
87
				options: textOptions
88
			},
89
			{
90
				data: SIDE_BIN,
91
				options: guardOptions
92
			},
93
		];
94
95
		if (this.options.displayValue) {
96
			data.unshift({
97
				data: '000000000000',
98
				text: this.text.substr(0, 1),
99
				options: { textAlign: 'left', ...textOptions }
100
			});
101
102
			if (this.options.lastChar) {
103
				data.push({
104
					data: '00'
105
				});
106
				data.push({
107
					data: '00000',
108
					text: this.options.lastChar,
109
					options: textOptions
110
				});
111
			}
112
		}
113
114
		return data;
115
	}
116
117
	encodeFlat() {
118
		const left = encode(this.leftData, EAN13_STRUCTURE[this.data[0]]);
119
		const right = encode(this.rightData, 'RRRRRR');
120
121
		return {
122
			data: [SIDE_BIN, left, MIDDLE_BIN, right, SIDE_BIN].join(''),
123
			text: this.text
124
		};
125
	}
126
127
}
128
129
export default EAN13;
130